<?php
namespace app\api\controller\v3;

use Exception;
use app\api\controller\v3\WxController;
class TestController
{
    //appId
    private $appId;
    //appSecret
    private $appSecret;
    //商户号
    private $mchId;
    //商户**
    private $mchKey;
    //本地路径
    private $path;
    //证书文件
    private $sslCert = 'apiclient_cert.pem';
    private $sslKey ;
    private $platCert = 'plat_cert.json';
    //api地址
    private $rootUrl = 'https://api.mch.weixin.qq.com/v3/';
    //api证书***
    private $serialNo;
    //商户私钥
    private $privateKey;
    //v3密钥
    private $platKey;
    //平台证书编号
    private $platSerialNo;
    //平台证书地址
    private $platPublicKey;
    //加密方式
    private $signAlg = 'sha256WithRSAEncryption';
    private $schema = 'WECHATPAY2-SHA256-RSA2048';
    //主机头
    private $httpHeader;
    //请求类型
    private $method = 'GET';
    //api接口
    private $panel = '';
    //随机字符串
    public $nonce = '';
    //时间戳
    public $stamp = 0;
    //报文主体
    public $body = '';
    //签名
    public $signature = '';
    /**
     * 构造函数
     */
    public function __construct(array $config)
    {
        $this->wx = new WxController();
        $this->appId = sys_config('routine_appId');
        $this->appSecret = isset($config['appSecret']) ? $config['appSecret'] : '';
        $this->mchId = sys_config('pay_weixin_mchid_v3');
        $this->mchKey = isset($config['mchKey']) ? $config['mchKey'] : '';
        $this->path = str_replace('\\', '/', public_path()."wx/");
        $this->sslCert =public_path() . getPemPath(sys_config('pay_weixin_client_key_v3'));
        $this->sslKey = public_path() . getPemPath(sys_config('pay_weixin_client_cert_v3'));
        $this->privateKey = public_path() . getPemPath(sys_config('pay_weixin_client_cert_v3'));
        $this->platCert = $this->path . (isset($config['platCert']) ? $config['platCert'] : $this->platCert);
        $folder = dirname($this->platCert);
        if (!is_dir($folder)) {//如果public下面没有wx这个文件夹就创建
            mkdir($folder, 0755, true);
        }
        $this->serialNo = sys_config('pay_weixin_serial_no') ;
        $this->platKey = isset($config['platKey']) ? $config['platKey'] : '';
        $this->platPublicKey = public_path()."/uploads/wx/pt.pem";

        $this->wx->certFicates();

    }
    /**
     * 预支付
     */
    public function prepay(array $data)
    {
        $data['appid'] = $this->appId;
        $data['mchid'] = $this->mchId;
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $this->method = 'POST';
        $this->panel = 'pay/transactions/jsapi';
        $this->body = $data;
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = json_decode($this->post($url, $data), true);
        return $result;
    }
    /**
     * JSAPI支付
     */
    public function invoke($preid)
    {
        $this->body = 'prepay_id=' . $preid;
        $this->buildSignature();
        $data = array(
            'timeStamp' => $this->stamp,
            'nonceStr' => $this->nonce,
            'package' => $this->body,
            'signType' => 'RSA',
            'paySign' => $this->signature,
        );
        return $data;
    }
    /**
     * 原生支付
     */
    public function native(array $data)
    {
        $data['appid'] = $this->appId;
        $data['mchid'] = $this->mchId;
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $this->method = 'POST';
        $this->panel = 'pay/transactions/native';
        $this->body = $data;
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = json_decode($this->post($url, $data), true);
        return $result;
    }
    /**
     * 合单
     */
    public function combine(array $data)
    {
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $this->method = 'POST';
        $this->panel = 'combine-transactions/jsapi';
        $this->body = $data;
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = json_decode($this->post($url, $data), true);
        p($result);exit;
        return $result;
    }
    /**
     * 上传图片
     */
    public function upload($file)
    {
        if (!$file && is_file($file)) {
            return false;
        }
        if (!in_array(pathinfo($file, PATHINFO_EXTENSION), array('jpg', 'png', 'bmp'))) {
            return false;
        }
        $file = str_replace('\\', '/', $file);
        $info = new \finfo(FILEINFO_MIME_TYPE);
        $mime = $info->file($file);
        $name = basename($file);
        $stream = file_get_contents($file);
        $meta = json_encode(array(
            'filename' => $name,
            'sha256' => hash_file('sha256', $file),
        ));
        $boundary = uniqid();
        $this->method = 'POST';
        $this->panel = 'merchant/media/upload';
        $this->body = $meta;
        $this->httpHeader = array(
            'Accept: application/json',
            'User-Agent: ' . $_SERVER['HTTP_USER_AGENT'],
            'Authorization: ' . $this->buildAuthorization(),
            'Content-Type: multipart/form-data;boundary=' . $boundary,
        );
        $url = $this->rootUrl . $this->panel;
        $sep = '--' . $boundary . "\r\n";
        $out = $sep;
        $out .= 'Content-Disposition: form-data; name="meta";' . "\r\n";
        $out .= 'Content-Type: application/json' . "\r\n";
        $out .= "\r\n";
        $out .= $meta . "\r\n";
        $out .= $sep;
        $out .= 'Content-Disposition: form-data; name="file"; filename="' . $name . '";' . "\r\n";
        $out .= 'Content-Type: ' . $mime . "\r\n";
        $out .= "\r\n";
        $out .= $stream . "\r\n";
        $out .= '--' . $boundary . '--' . "\r\n";
        $result = json_decode($this->post($url, $out), true);
        return $result;
    }
    /**
     * 二级商户进件
     */
    public function applyment(array $data)
    {
        if (!isset($data['id_card_info']['id_card_name'])) {
            return false;
        }
        if (!isset($data['id_card_info']['id_card_number'])) {
            return false;
        }
        if (!isset($data['account_info']['account_name'])) {
            return false;
        }
        if (!isset($data['account_info']['account_number'])) {
            return false;
        }
        if (!isset($data['contact_info']['contact_name'])) {
            return false;
        }
        if (!isset($data['contact_info']['contact_id_card_number'])) {
            return false;
        }
        if (!isset($data['contact_info']['mobile_phone'])) {
            return false;
        }
        if (!isset($data['contact_info']['contact_email'])) {
            return false;
        }
        $data['appid'] = $this->appId;
        $data['id_card_info']['id_card_name'] = $this->encrypt($data['id_card_info']['id_card_name']);
        $data['id_card_info']['id_card_number'] = $this->encrypt($data['id_card_info']['id_card_number']);
        $data['account_info']['account_name'] = $this->encrypt($data['account_info']['account_name']);
        $data['account_info']['account_number'] = $this->encrypt($data['account_info']['account_number']);
        $data['contact_info']['contact_name'] = $this->encrypt($data['contact_info']['contact_name']);
        $data['contact_info']['contact_id_card_number'] = $this->encrypt($data['contact_info']['contact_id_card_number']);
        $data['contact_info']['mobile_phone'] = $this->encrypt($data['contact_info']['mobile_phone']);
        $data['contact_info']['contact_email'] = $this->encrypt($data['contact_info']['contact_email']);
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $this->method = 'POST';
        $this->panel = 'ecommerce/applyments/';
        $this->body = $data;
        $this->buildHeader(true);
        $url = $this->rootUrl . $this->panel;
        $result = json_decode($this->post($url, $data), true);
        return $result;
    }
    /**
     * 二级商户审核状态查询
     */
    public function auditState($no, $type = 0)
    {
        if (!$no) {
            return false;
        }
        $this->method = 'GET';
        $this->panel = 'ecommerce/applyments/' . ($type ? 'out-request-no/' : '') . $no;
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = json_decode($this->get($url), true);
        return $result;
    }
    /**
     * 添加分账接收方
     */
    public function addReceivers(array $data)
    {
        if (!isset($data['name'])) {
            return false;
        }
        $data['appid'] = $this->appId;
        $data['sub_mchid'] = '1653284709';
        $data['custom_relation'] = "合作关系";
        $data['name'] = $this->wx->getEncrypt($data['name']);
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $this->method = 'POST';
        $this->panel = 'profitsharing/receivers/add';
        $this->body = $data;
        $url = $this->rootUrl . $this->panel;
        $bodyData  = $data;
        $this->buildHeader(true);
        $result= $this->wx->getCurl('POST', $url, $bodyData, $this->httpHeader);
        $result = json_decode($result,true);
//        $result = json_decode($this->post($url, $bodyData), true);
        return $result;
    }
    /**
     * 删除分账接收方
     */
    public function delReceivers(array $data)
    {
        if (!isset($data['name'])) {
            return false;
        }
        $data['appid'] = $this->appId;
        $data['sub_mchid'] = '1653284709';
        $data['name'] = $this->wx->getEncrypt($data['name']);
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $this->method = 'POST';
        $this->panel = 'profitsharing/receivers/delete';
        $this->body = $data;
        $url = $this->rootUrl . $this->panel;
        $bodyData  = $data;
        $this->buildHeader(true);
        $result= $this->wx->getCurl('POST', $url, $bodyData, $this->httpHeader);
//        $result = json_decode($this->post($url, $bodyData), true);
        return $result;
    }
    /**
     * 分账
     */
    public function divide(array $data)
    {
        if (!$data && is_array($data)) {
            return false;
        }
        $data['appid'] = $this->appId;
        $data['sub_mchid'] = $data['sub_mchid'];
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $this->method = 'POST';
        $this->panel = 'profitsharing/orders';
        $this->body = $data;
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = json_decode($this->post($url, $data), true);
        return $result;
    }

    /**
     * 分账回退
     */
    public function return_divide(array $data)
    {
        if (!$data && is_array($data)) {
            return false;
        }
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $this->method = 'POST';
        $this->panel = 'profitsharing/return-orders';
        $this->body = $data;
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = json_decode($this->post($url, $data), true);
        return $result;
    }

    /**
     * 解冻剩余资金
     */
    public function unfreeze(array $data)
    {
        if (!$data && is_array($data)) {
            return false;
        }
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $this->method = 'POST';
        $this->panel = 'profitsharing/orders/unfreeze';
        $this->body = $data;
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = json_decode($this->post($url, $data), true);
        return $result;
    }

    /**
     * 查询剩余待分金额
     */
    public function get_daifen_amounts(array $data)
    {
        if (!$data && is_array($data)) {
            return false;
        }
        $this->method = 'GET';
        $this->panel = 'profitsharing/transactions/'.$data['transaction_id'].'/amounts';
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
//        $this->body = $data;
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
//        $result = json_decode($this->getCurl($url), true);
        $result = $this->getCurl('GET', $url, '', []);
        p($result);exit;
        return $result;
    }

    /**
     * 查询分账结果
     */
    public function get_split_result(array $data,$mchid)
    {
        if (!$data && is_array($data)) {
            return false;
        }
        $this->method = 'GET';
        $this->panel = 'profitsharing/orders/'.$data['out_order_no']."?sub_mchid=".$data['sub_mchid']."&transaction_id=".$data['transaction_id'];
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = $this->getCurl('GET', $url, '', []);
        return $result;
    }

    /**
     * 微信支付订单号查询订单
     */
    public function get_order(array $data)
    {
        if (!$data && is_array($data)) {
            return false;
        }
        $a = 1652272678;
        $data['sub_mchid'] = 1653284709;
        $this->method = 'GET';
        $this->panel = 'pay/partner/transactions/out-trade-no/'.$data['order_no'].'-0'."?sp_mchid=".$a."&sub_mchid=".$data['sub_mchid'];
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = $this->getCurl('GET', $url, '', []);
        return $result;
    }

    /**
     * 微信支付订单号查询订单
     */
    public function get_order2(array $data)
    {
        if (!$data && is_array($data)) {
            return false;
        }
//        $a = 1652272678;
//        $data['sub_mchid'] = 1653284709;
        $this->method = 'GET';
        $this->panel = 'pay/transactions/out-trade-no/'.$data['order_no'].'-0'."?mchid=".$data['mchid'];
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = $this->getCurl('GET', $url, '', []);
        return $result;
    }

    /**
     * 生成Header
     */
    private function buildHeader($usePlatSerial = false)
    {
        $url = $this->rootUrl . $this->panel;
        // 获取认证信息
        $authorization = $this->wx->getAuthorization($url,$this->method,$this->body);
        // 获取支付平台证书编码(也可以用接口中返回的serial_no  来源：https://api.mch.weixin.qq.com/v3/certificates)
        $serial_no = $this->wx->parseSerialNo( $this->wx->getCertFicates());
        $this->httpHeader        = [
            'Content-Type:application/json',
            'Accept:application/json',
            'User-Agent:*/*',
            'Authorization:' . $authorization,
            'Wechatpay-Serial:' . $serial_no
        ];
        if ($this->body) {
            $this->httpHeader[] = 'Content-Length: ' . strlen($this->body);
        }
    }

    /**
     * 生成Authorization
     */
    private function buildAuthorization()
    {
        $this->signer();
        $token  = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
            $this->mchId, $this->nonce, $this->stamp, $this->serialNo, $this->signature);
        $schema = 'WECHATPAY2-SHA256-RSA2048';
        return $schema . ' ' . $token;

    }
    /**
     * 签名生成器
     */
    private function signer()
    {
        $this->stamp = time();
        $this->nonce = buildNonceStr();
        $message       = $this->method . "\n" .
            $this->panel . "\n" .
            $this->stamp . "\n" .
            $this->nonce . "\n" .
            $this->body . "\n";
        openssl_sign($message, $signature, \openssl_get_privatekey(\file_get_contents($this->privateKey)), $this->signAlg);
        $this->signature = base64_encode($signature);
    }
    /**
     * 生成JSSDK签名
     */
    private function buildSignature()
    {
        $this->stamp = time();
        $this->nonce = buildNonceStr();
        $message = $this->appId . "\n" . $this->stamp . "\n" . $this->nonce . "\n" . $this->body . "\n";
        openssl_sign($message, $signature, $this->privateKey, $this->signAlg);
        $this->signature = base64_encode($signature);
    }

    /*
     * get请求
     */
    private function get($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this->httpHeader);
        $out = curl_exec($ch);
        curl_close($ch);
        return $out;
    }
    /*
     * post请求
     */
    private function post($url, $data = '')
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this->httpHeader);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }

    /**
     * @param string       $method
     * @param string       $url
     * @param array|string $data
     * @param array        $headers
     * @param int          $timeout
     * @return bool|string
     */
    public function getCurl($method = 'GET', $url, $data, $headers = [], $timeout = 10)
    {
        $headers = $this->httpHeader;
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HEADER, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);

        if (!empty($headers)) {
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        }
        if ($method == 'POST') {
            curl_setopt($curl, CURLOPT_POST, TRUE);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        else {
        }
        $result = curl_exec($curl);

        curl_close($curl);
        return $result;
    }


}